package com.jcfriends.common.util;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.SimpleTimeZone;


public class DateUtils {

	public static Locale DEFAULT_LOCALE = Locale.KOREA;	

	public static final String NONE_DATE_FORMAT		= "yyyyMMdd";
	public static final String DASH_DATE_FORMAT		= "yyyy-MM-dd";
	public static final String SLASH_DATE_FORMAT	= "yyyy/MM/dd";

	public static final String DEFAULT_DATE_FORMAT		= NONE_DATE_FORMAT;

	public static final String[] formatList = {"-", "/", "_"};


	/**
	 * 현재 날짜
	 * @return
	 */
	public static String getFullDate(){
		return getFullDate( new Date(), DEFAULT_DATE_FORMAT );
	}

	/**
	 * 현재 날짜를 해당 포멧형식으로 변경
	 * @param format
	 * @return
	 */
	public static String getFullDate(String format){
		return getFullDate( new Date(), format );
	}

	/**
	 * 특정 날짜
	 * @param date
	 * @return
	 */
	public static String getFullDate(Date date){
		return getFullDate( date, DEFAULT_DATE_FORMAT );
	}

	/**
	 * 특정 날짜를 해당 포멧형식으로 변경
	 * @param date
	 * @param format
	 * @return
	 */
	public static String getFullDate(Date date, String format){
		return getSimpleDateFormat( format ).format( date );
	}

	/**
	 * 오늘 날짜에 월(달)을 추가함.
	 * @param addCnt 추가할 월(달)
	 * @return
	 */
	public static String getAddedMonth(int addCnt){
		return getAddedMonth(addCnt, DEFAULT_DATE_FORMAT);
	}

	/**
	 * 오늘 날짜에 월(달)을 추가함.
	 * @param addCnt 추가할 월(달)
	 * @param format 날짜 포멧형식
	 * @return
	 */
	public static String getAddedMonth(int addCnt, String format){
		return getAdded(Calendar.MONTH, addCnt, format, new Date());	
	}

	/**
	 * 입력된 날짜에 월(달)을 추가함.
	 * @param addCnt 추가할 월(달)
	 * @param date 대상 날짜
	 * @return
	 */
	public static String getAddedMonthInDate(int addCnt, Date date){
		return getAddedMonthInDate(addCnt, DEFAULT_DATE_FORMAT, date);
	}

	/**
	 * 입력된 날짜에 월(달)을 추가함.
	 * @param addCnt 추가할 월(달)
	 * @param format 날짜 포멧형식
	 * @param date 대상 날짜
	 * @return
	 */
	public static String getAddedMonthInDate(int addCnt, String format, Date date){
		return getAdded(Calendar.MONTH, addCnt, format, date);
	}

	/**
	 * 오늘 날짜에 일수를 추가함.
	 * @param addCnt 추가할 일수(음수는 전일)
	 * @return
	 */
	public static String getAddedDate(int addCnt){
		return getAddedDate(addCnt, DEFAULT_DATE_FORMAT);
	}

	/**
	 * 오늘 날짜에 일수를 추가함.
	 * @param addCnt 추가할 일수(음수는 전일)
	 * @param format 날짜 포멧형식
	 * @return
	 */
	public static String getAddedDate(int addCnt, String format){
		return getAdded(Calendar.DATE, addCnt, format, new Date());		
	}

	/**
	 * 입력된 날짜에 일수를 추가함.
	 * @param addCnt 추가할 일수(음수는 전일)
	 * @param date 대상 날짜
	 * @return
	 */
	public static String getAddedDateInDate(int addCnt, Date date){
		return getAddedDateInDate(addCnt, DEFAULT_DATE_FORMAT, date);
	}

	/**
	 * 입력된 날짜에 일수를 추가함.
	 * @param addCnt 추가할 일수(음수는 전일)
	 * @param format 날짜 포멧형식
	 * @param date 대상 날짜
	 * @return
	 */
	public static String getAddedDateInDate(int addCnt, String format, Date date){
		return getAdded(Calendar.DATE, addCnt, format, date);		
	}

	/**
	 * 입력된 날짜를 변경한다.
	 * @param field
	 * @param addCnt
	 * @param format
	 * @param date
	 * @return
	 */
	private static String getAdded(int field, int addCnt, String format, Date date){
		Calendar calendar= getTargetCalendar(date);
		calendar.add(field, addCnt);
		return getFullDate(calendar.getTime(), format);
	}

	/**
	 * 문자열로 구성된 날짜를 기본 포멧형식으로 지정 후 Date 리턴
	 * @param fullDate
	 * @return
	 */
	public static Date stringToDate(String fullDate){
		return stringToDate(fullDate, DEFAULT_DATE_FORMAT);
	}

	/**
	 * 문자열로 구성된 날짜를 입력된 포멧형식으로 지정 후 Date 리턴
	 * @param fullDate
	 * @param format
	 * @return
	 */
	public static Date stringToDate(String fullDate, String format){
		return getSimpleDateFormat(format).parse(fullDate, new ParsePosition(0));
	}

	/**
	 * 오늘 날짜의 Calendar 생성
	 * @return
	 */
	private static Calendar getCalendar(){
		return Calendar.getInstance();
	}

	/**
	 * Date -> Calendar
	 * @param date
	 * @return
	 */
	public static Calendar getTargetCalendar(Date date){
		Calendar calendar = getCalendar();
		calendar.setTime(date);
		return calendar;
	}

	/**
	 * SimpleDateFormat 생성 ( format : DEFAULT_DATE_FORMAT, locale : DEFAULT_LOCALE )
	 * @return
	 */
	private static SimpleDateFormat getSimpleDateFormat(){
		return getSimpleDateFormat(DEFAULT_DATE_FORMAT);
	}

	/**
	 * SimpleDateFormat 생성 ( format : 사용자지정, locale : DEFAULT_LOCALE ) 
	 * @param format
	 * @return
	 */
	private static SimpleDateFormat getSimpleDateFormat(String format){
		return getSimpleDateFormat(format, DEFAULT_LOCALE);
	}

	/**
	 * SimpleDateFormat 생성 ( format, locale : 사용자 지정 )
	 * @param format
	 * @param locale
	 * @return
	 */
	private static SimpleDateFormat getSimpleDateFormat(String format, Locale locale){
		return new SimpleDateFormat(format, locale);
	}


	/**
	 * 문자열로된 날짜의 포멧형식을 제거.
	 * @param dateStr
	 * @return
	 */
	public static String removeFormat(String dateStr){

		try{
			for(String format : formatList){
				if(dateStr.length() == 8) return dateStr;

				dateStr = dateStr.replaceAll(format, "");
			}			
		}catch(Exception e){
			return dateStr;
		}

		return dateStr;

	}


	//	===================================== [ L e g a c y ] =====================================




	/**
	 * 현재 년월일(YYYYMMDD)
	 * @deprecated
	 * @return
	 */
	public static String getCurrentDay(){
		return getFullDate();
	}

	/**
	 * @deprecated
	 * @return
	 */
	public static Calendar getInstanceCalendar(){
		return new GregorianCalendar(new SimpleTimeZone(9*60*60*1000,"KST"));
	}

	/**
	 * 현재 년도(YYYY)
	 * @deprecated
	 * @return
	 */
	public static int getYear(){
		return getCalendar().get(Calendar.YEAR);
	}


	/**
	 * 현재월(MM)
	 * @deprecated
	 * @return
	 */
	public static int getMonth(){
		return getCalendar().get(Calendar.MONTH)+1;
	}

	/**
	 * 현재일(DD)
	 * @deprecated
	 * @return
	 */
	public static int getDay(){
		return getCalendar().get(Calendar.DAY_OF_MONTH);
	}
}